package com.LeeG.work.Sort;

import java.util.Arrays;

/**
 * @author LeeG
 * @Description: 排序抽象类
 * @date 2021/1/17 17:59
 */
public abstract class Sort {
    /**
     * 待排序数组
     */
    protected int[] array;
    /**
     * 比较次数
     */
    protected Integer cmpCount = 0;
    /**
     * 交换次数
     */
    protected Integer swapCount = 0;
    /**
     * 运行结束标志
     */
    protected boolean flag = true;

    public void sort(int[] array) {
        if(array == null || array.length < 2) {
            return;
        }
        this.array = array;
        int[] arr2 = copyArray(array);
        comparator(arr2);
        long startTime = System.currentTimeMillis();
        while (flag){
            sort();
            if (isEqual(array, arr2)) {
                break;
            } else {
                flag = false;
            }
        }
        sort();
        long endTime = System.currentTimeMillis();
        System.out.print(flag ? "运行成功\t\t" : "运行失败\n");
        if(flag) {
            System.out.printf(" 比较次数:%-10d\t交换次数:%-10d\t", cmpCount, swapCount);
            System.out.println("耗时:" + (endTime - startTime) + "ms");
        }
    }

    /**
     * 抽象方法排序，由子类实现
     */
    public abstract void sort();

    /**
     * 拷贝数组
     * @param arr
     * @return
     */
    public static int[] copyArray(int[] arr) {
        int[] copyArray = new int[arr.length];
        for(int i = 0; i < arr.length; i++) {
            copyArray[i] = arr[i];
        }
        return copyArray;
    }

    /**
     * 调用API，排序数组
     * @param arr
     */
    public static void comparator(int[] arr) {
        Arrays.sort(arr);
    }

    /**
     * 根据下标，交换数组元素
     * @param i
     * @param j
     */
    protected void swap(int i, int j) {
        swapCount++;
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    /**
     * 根据下标，比较数组元素
     * @param i
     * @param j
     * @return
     */
    protected int cmp(int i, int j) {
        cmpCount++;
        if(array[i] < array[j]) {
            return -1;
        } else if(array[i] == array[j]) {
            return 0;
        } else {
            return 1;
        }
    }

    /**
     * 比较数组元素
     * @param a
     * @param b
     * @return
     */
    protected int cmpValue(int a, int b) {
        cmpCount++;
        if(a < b) {
            return -1;
        } else if(a == b) {
            return 0;
        } else {
            return 1;
        }
    }

    /**
     * 打印数组
     * @param array
     */
    protected void print(int[] array) {
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }

    /**
     * 判断两数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    public static Boolean isEqual(int[] arr1, int[] arr2) {
        for(int i = 0;i < arr1.length; i++) {
            if(arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }
}
